﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Drawing;
using System.Data;
using System.Text;
using System.Windows.Forms;
using System.IO;
using System.Reflection;

namespace Walson.Form.Common
{
    /// <summary>
    /// 旋钮
    /// </summary>
    public partial class RoundTuner : Control
    {

        private Bitmap _Tuner;
        private Size _TunerSize;
        private Size _OriginalSize;

        private float _angle = 0;

        private int _Multiply = 1;
        private int _TimerTick = 0;
        private float _TunerScaleFactor = 1.0f;

        private Timer _IntervalTimer;

        private bool _MouseOnLeft = false;
        private bool _TimerTicked = false;

        private int _Value = 0;
        /// <summary>
        /// 旋钮的当前值
        /// </summary>
        public int Value
        {
            get
            {
                return _Value;
            }
            set
            {
                if (UnLimited == false)
                {
                    if (value > _Max)
                    {
                        value = value - _Max + _Min;
                    }
                    if (value < _Min)
                    {
                        value = _Max - (_Min - value);
                    }
                }

                _Value = value;
                _angle = 1f*(_Value - _Min) / _Max * 360f;
                Raise_ValueChangedEvent();
                this.Invalidate();
            }
        }

        /// <summary>
        /// 指示旋钮是否在超过最大值以后返回最小值，或超过最小值以后返回最大值
        /// </summary>
        public bool UnLimited
        {
            get;
            set;
        }

        private float _AngleIncreasement = 1;
        /// <summary>
        /// 值每增加1，旋钮旋转的角度
        /// </summary>
        public float AngleIncreasement
        {
            get
            {
                return _AngleIncreasement;
            }
            private set
            {
                _AngleIncreasement = value;
                this.Invalidate();
            }
        }

        private int _Increasement = 1;
        /// <summary>
        /// 转动的最小增量
        /// </summary>
        public int Increasement
        {
            get
            {
                return _Increasement;
            }
            set
            {
                _Increasement = value;
                this.Invalidate();
            }
        }

        private int _Min = 0;
        /// <summary>
        /// 最小值
        /// </summary>
        public int Min
        {
            get
            {
                return _Min;
            }
            set
            {
                _Min = value;
                _AngleIncreasement = 360f / (_Max - _Min);
                this.Invalidate();
            }
        }

        private int _Max = 100;
        /// <summary>
        /// 最小值
        /// </summary>
        public int Max
        {
            get
            {
                return _Max;
            }
            set
            {
                if (value <= _Min)
                    return;
                _Max = value;
                this.Invalidate();
            }
        }


        /// <summary>
        /// 旋钮
        /// </summary>
        public RoundTuner()
        {
            InitializeComponent();

            this.DoubleBuffered = true;

            LoadResource();
            this.MouseDown += new MouseEventHandler(Tuner_MouseDown);
            this.MouseUp += new MouseEventHandler(Tuner_MouseUp);
            this.MouseClick += new MouseEventHandler(Tuner_MouseClick);
            this.SizeChanged += new EventHandler(RoundTuner_SizeChanged);
            _IntervalTimer = new System.Windows.Forms.Timer();
            _IntervalTimer.Interval = 100;
            _IntervalTimer.Tick += delegate
            {
                _TimerTicked = true;
                _TimerTick++;
                if (_TimerTick == 10)
                    _Multiply = 2;
                    //_IntervalTimer.Interval = 50;
                if (_TimerTick == 20)
                {
                    _Multiply = 10;
                }
                if (_TimerTick == 40)
                {
                    _Multiply = 100;
                }
                if (_TimerTick == 80)
                {
                    _Multiply = 1000;
                }
                if (_TimerTick == 160)
                {
                    _Multiply = 10000;
                }
                if (_MouseOnLeft)
                {
                    _angle -= _AngleIncreasement * _Multiply;
                    Value -= _Increasement * _Multiply;
                }
                else
                {
                    _angle += _AngleIncreasement * _Multiply;
                    Value += _Increasement * _Multiply;
                }
//                 if (_Value < 0)
//                     _Value = 0;
                //Raise_ValueChangedEvent();
                this.Invalidate();
            };
        }

        void RoundTuner_SizeChanged(object sender, EventArgs e)
        {
            
            int min = Math.Min(this.Width, this.Height);
            int r = -min / 2;
            try
            {
                _TunerScaleFactor = ((float)min / (float)_OriginalSize.Width);
            }
            catch (System.Exception)
            {
                _TunerScaleFactor = 1f;
            }

            if (_TunerScaleFactor <= 0)
                _TunerScaleFactor = 1f;
            //MessageBox.Show(min.ToString()+"\r\n"+_OriginalSize.Width.ToString()+"\r\n"+_TunerScaleFactor.ToString());
            LoadResource();
            this.Invalidate();
        }

      

        void Tuner_MouseClick(object sender, MouseEventArgs e)
        {
            if (e.Button != MouseButtons.Left)
            {
                return;
            }

            if (e.X <= this.Width / 2)
            {
                _MouseOnLeft = true;
            }
            else
            {
                _MouseOnLeft = false;
            }

            this.Focus();
        }

        void Tuner_MouseDown(object sender, MouseEventArgs e)
        {
            if (e.X <= this.Width / 2)
            {
                _MouseOnLeft = true;
            }
            else
            {
                _MouseOnLeft = false;
            }

            _TimerTicked = false;
            _IntervalTimer.Interval = 100;
            _IntervalTimer.Enabled = true;
        }

        void Tuner_MouseUp(object sender, MouseEventArgs e)
        {
            _IntervalTimer.Enabled = false;
            _TimerTick = 0;
            _Multiply = 1;

            if (_TimerTicked == false)
            {
                if (_MouseOnLeft)
                {
                    Value -= _Increasement;
                    _angle -= _AngleIncreasement;
                }
                else
                {
                    Value += _Increasement;
                    _angle += _AngleIncreasement;
                }
                
                this.Invalidate();
            }
        }

       
        private void LoadResource()
        {
            Assembly myAssembly = Assembly.GetExecutingAssembly();
            Stream myStream = myAssembly.GetManifestResourceStream("Walson.Resources.Tuner.png");
            Bitmap bmp = new Bitmap(myStream);
            Bitmap bmp2 = new Bitmap((int)(bmp.Width * _TunerScaleFactor), (int)(bmp.Height * _TunerScaleFactor));

            using (Graphics g = Graphics.FromImage(bmp2))
            {
                g.ScaleTransform(_TunerScaleFactor, _TunerScaleFactor);
                g.DrawImage(bmp, 0, 0);
                g.ResetTransform();

            }

            _Tuner = bmp2;
            _TunerSize = bmp2.Size;
            _OriginalSize = bmp.Size;
        }

        /// <summary>
        /// 绘制
        /// </summary>
        /// <param name="e">参数</param>
        protected override void OnPaint(PaintEventArgs e)
        {
            if (_Tuner == null)
                return;

            using (Bitmap bmp = new Bitmap(this.Width, this.Height))
            {
                using (Graphics g = Graphics.FromImage(bmp))
                {
                    g.SmoothingMode = System.Drawing.Drawing2D.SmoothingMode.AntiAlias;

                    g.TranslateTransform(this.Width / 2, this.Height / 2);
                    g.RotateTransform(_angle);
                    g.DrawImage(_Tuner, -_Tuner.Width / 2, -_Tuner.Height / 2);
                }
                e.Graphics.DrawImage(bmp, 0, 0);

                Rectangle rect = new Rectangle(0, 0, base.Width, base.Height);
                int r = _Tuner.Width / 2 /*- (int)(20 * _TunerScaleFactor)*/;
                System.Drawing.Drawing2D.GraphicsPath roundRect = new System.Drawing.Drawing2D.GraphicsPath();
                roundRect.AddEllipse(this.Width / 2 - r, this.Height / 2 - r, r*2, r*2);
                this.Region = new Region(roundRect);
                base.OnPaint(e);
            }
        }

        /// <summary>
        /// 值改变事件处理方法
        /// </summary>
        /// <param name="sender">事件发送者</param>
        public delegate void ValueChangedHandler(object sender);
        /// <summary>
        /// 值改变事件
        /// </summary>
        public event ValueChangedHandler ValueChanged;
        /// <summary>
        /// 触发值改变事件
        /// </summary>
        protected void Raise_ValueChangedEvent()
        {
            if (this.ValueChanged != null)
                ValueChanged((object)this);
        }
        
    }
}
